package cn.huiyunche.driver.service.impl;

import cn.huiyunche.base.service.enums.TmsDispatchOptionCodeEnum;
import cn.huiyunche.base.service.framework.utils.TmsQueueApi;
import cn.huiyunche.base.service.interfaces.*;
import cn.huiyunche.base.service.mappers.DVcstyleLicenseMapper;
import cn.huiyunche.base.service.mappers.DWaybillMapper;
import cn.huiyunche.base.service.mappers.TmsOrderMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.utils.JavaSmsApi;
import cn.huiyunche.base.service.vo.TmsBareaVo;
import cn.huiyunche.base.service.vo.TmsQueueDriverVo;
import cn.huiyunche.base.service.vo.TmsQueueOrderVo;
import cn.huiyunche.driver.service.DVcstyleLicenseService;
import cn.huiyunche.driver.service.DWaybillErrorMsgService;
import cn.huiyunche.driver.service.PublishWaybillFromDBService;
import cn.huiyunche.driver.service.TmsQueueDimensionService;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * 司机维度 派单服务
 *
 * @author hdy [Tuffy]
 */
@Service
public class TmsQueueDimensionServiceImpl implements TmsQueueDimensionService {

    private static final Logger LOGGER = LoggerFactory.getLogger(TmsQueueDimensionServiceImpl.class);
    private final String provinceSuffix = "省";
    private final String citySuffix = "市";
    private Long driverIndex = 0L;

    @Autowired
    private DUserAddressService dUserAddressService = null;

    @Autowired
    private DWaybillService dWaybillService = null;

    @Autowired
    private SendMessageService sendMessageService;
	
	@Autowired
	private DWaybillMapper dWaybillMapper = null;
	
	@Autowired
	private TmsOrderMapper tmsOrderMapper = null;

	@Autowired
	private DVcstyleLicenseService dVcstyleLicenseService = null;
	
	@Autowired
	private DVcstyleLicenseMapper dVcstyleLicenseMapper = null;

    @Autowired
    private DWaybillErrorMsgService dWaybillErrorMsgService;

    @Autowired
    private UserService userService;

    @Autowired
    private DWaybillVehicleService dWaybillVehicleService;

    @Autowired
    private PublishWaybillFromDBService publishWaybillFromDBService;

    @Override
    public void startDispatch() {
        LOGGER.info("================调度开始，启动队列===============");
        if (!TmsQueueApi.isRootStartQueue()) {
            LOGGER.info("TmsQueueDimensionServiceImpl.startDispatch rootStartQueue is false");
            return;
        }
//		if (TmsQueueApi.isStartQueue()) {
//			LOGGER.info("TmsQueueDimensionServiceImpl.startDispatch startQueue will progress");
//			return;
//		}

        TmsQueueApi.setStartQueue(true);

        // 初始化司机队列索引
        this.driverIndex = 0L;
        // 派单开始
        this.dispatch();

        //将数据库中可用的运单导入到redis中
        publishWaybillFromDBService.db2Redis();
    }

    /**
     * 开始派单
     */
    private void dispatch() {

        LOGGER.info("TmsQueueDimensionServiceImpl.dispatch is progress");

        TmsQueueDriverVo driver = null;
        TmsQueueOrderVo waybill = null;

        try {

            /**
             * 获取队列司机
             */
            driver = this.alreadyExistsDriver();
            if (null == driver) {
                LOGGER.info("TmsQueueDimensionServiceImpl.dispatch is no driver");
                TmsQueueApi.setStartQueue(false);
                throw new BusinessException("没有司机");
            }

            List<TmsQueueOrderVo> orders = TmsQueueApi.orderList();

            if (CollectionUtils.isNotEmpty(orders) && null != driver) {
                // 派单
                this.matchOrder(orders, driver);
            }

            TmsQueueApi.setStartQueue(false);

        } catch (Exception e) {

            LOGGER.error("TmsQueueDimensionServiceImpl.dispatch error : {}, {}, {}", driver, waybill, e);

            TmsQueueApi.setStartQueue(false);
        }
    }

    private TmsQueueOrderVo alreadyExistsWaybill(TmsQueueDriverVo driver) {

//        TmsQueueOrderVo enableWaybill = null;

        List<TmsQueueOrderVo> waybills = TmsQueueApi.orderList();
        if ( CollectionUtils.isEmpty(waybills) ) {
            TmsQueueApi.setStartQueue(false);

            LOGGER.error("TmsQueueDimensionServiceImpl.alreadyExistsWaybill has no waybill");
            throw new BusinessException("没有运单") ;
        }

        return waybills.get(0);
//        try {
//
//            // 司机意愿路线
//            List<TmsBareaVo> intentionalLinesList = dUserAddressService.getListByPhone(driver.getPhone());
//
//            //取司机选中的意向线路
//            List<TmsBareaVo> collect = intentionalLinesList.stream().filter(e -> e.getIsCheck() == true).collect(Collectors.toList());
//
//            //未选中
//            if( CollectionUtils.isEmpty(collect) ){
//
//                LOGGER.error("TmsQueueDimensionServiceImpl.alreadyExistsWaybill intentionalLinesList must not be null");
//                throw new BusinessException(TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_INTENTIONA_LINE.getValue()+"", TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_INTENTIONA_LINE.getText());
//            }
//
//            /**
//             *  匹配运单
//             */
//            Iterator<TmsQueueOrderVo> iterator = waybills.iterator();
//            while (iterator.hasNext()){
//                enableWaybill = iterator.next();
//
//                DWaybill dWaybill = dWaybillService.selectByOrderLineId(NumberUtils.toLong(enableWaybill.getTmsSerialNo()));
//
//                //如果运单在数据库中不存在或已经派送了（userId不等于）则移除
//                if( null == dWaybill && 0 != dWaybill.getUserId()){
//                    LOGGER.error("TmsQueueDimensionServiceImpl.alreadyExistsWaybill dWaybillot exist in database ");
//                    TmsQueueApi.removeOrder(enableWaybill);
//                    iterator.remove();
//                    continue;
//                }else{
//
//                    boolean isMatch = validVcStyleLicense(enableWaybill, driver);
//
//                    if(isMatch){
//                        if (this.filterAvailableOrder(enableWaybill, intentionalLinesList)) {
////                            enableWaybill = enableWaybill;
//                            break;
//                        }
//                    }
//                }
//
//            }
//        }catch (Exception e){
//            LOGGER.error("TmsQueueDimensionServiceImpl.alreadyExistsWaybill error : {}", e);
//
//            if( e instanceof BusinessException ){
//                String messageCode = ((BusinessException) e).getMessageCode();
//
//                if( null != messageCode ){
//                    this.handleError(enableWaybill, driver, messageCode, e);
//                }
//            }
//        }

//        return enableWaybill;
    }

    private TmsQueueDriverVo alreadyExistsDriver() {

        LOGGER.info("========当前派单司机所在队列位置============ {}", this.driverIndex);

        TmsQueueDriverVo driver = TmsQueueApi.getDriverByIndex(this.driverIndex);

        if (null != driver) {

//            TmsQueueApi.setStartQueue(false);

            return driver;
        }

        return null;
    }

    /**
     * 开始派单
     *
     * @param redisWaybills 队列订单对象
     * @param driver        队列司机对象
     */
	private void matchOrder(List<TmsQueueOrderVo> redisWaybills, TmsQueueDriverVo driver) throws Exception {
		LOGGER.info("================队列开始派单=============");

        if (CollectionUtils.isEmpty(redisWaybills)) {
            LOGGER.error("TmsQueueDimensionServiceImpl.order redisWaybills must not be empty : {}", redisWaybills);
            throw new BusinessException(TmsDispatchOptionCodeEnum.WAYBILL_IS_NULL.getValue() + "", TmsDispatchOptionCodeEnum.WAYBILL_IS_NULL.getText());
        }

        //待匹配的运单
        TmsQueueOrderVo redisWaybill = null;

        //匹配成功的运单
        DWaybill waybill = null;

        //线路是否匹配
        boolean lineIsMatch = false;

        //司机驾照是否匹配
        boolean licenseIsMatch = false;

        try {

            /**
             *  qichao
             *  FIXME 整个账号体系需要重构
             *  校验当前司机是否存在，若不存在，则移除司机（当前是从redis取司机信息，根据司机的手机号，去mysql取意向路线，若后台变更了司机的手机号，则会NPE）
             */
            SUser user = userService.getUserByPhone(driver.getPhone());

            if(Objects.equals(user,null)){
                throw new BusinessException(TmsDispatchOptionCodeEnum.DRIVER_WRONG_PHONE_NO.getValue()+"",TmsDispatchOptionCodeEnum.DRIVER_WRONG_PHONE_NO.getText());
            }

            //查询司机意愿路线
            List<DUserAddress> intentionalLinesList = dUserAddressService.geUserCheckedList(user.getId());

            //如果司机未选意向线路线路
            if (CollectionUtils.isEmpty(intentionalLinesList)) {

                LOGGER.error("TmsQueueDimensionServiceImpl.alreadyExistsWaybill intentionalLinesList must not be null");
                throw new BusinessException(TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_INTENTIONA_LINE.getValue() + "", TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_INTENTIONA_LINE.getText());
            }

            String provinces = intentionalLinesList.stream().map(DUserAddress::getReceiptProvinceName).reduce("", (x, y) -> x + y + ",");

            /**
             *  匹配线路运单
             */
            Iterator<TmsQueueOrderVo> iterator = redisWaybills.iterator();
            while (iterator.hasNext()) {
                TmsQueueOrderVo next = redisWaybill = iterator.next();

                DWaybill dWaybill = dWaybillService.selectByOrderLineId(NumberUtils.toLong(next.getTmsSerialNo()));

                //如果运单在数据库中不存在或已经派送了（userId不等于0）则移除
                if (null == dWaybill || 0 != dWaybill.getUserId()) {
                    LOGGER.error("TmsQueueDimensionServiceImpl.alreadyExistsWaybill dWaybillot exist in database ");
                    TmsQueueApi.removeOrder(next);
                    iterator.remove();
                    continue;
                } else {

                    //匹配意向线路
                    if (StringUtils.isNotBlank(provinces) && provinces.contains(dWaybill.getDestProvince().replaceAll(provinceSuffix, "").replaceAll(citySuffix, ""))) {
                        LOGGER.info("TmsQueueDimensionServiceImpl.matchOrder driver intentional line is match : {}, {}", dWaybill.getId(), driver.getPhone());
                        lineIsMatch = true;

                        //匹配驾照
                        if (validVcStyleLicense(next, driver, dWaybill)){
                            LOGGER.info("TmsQueueDimensionServiceImpl.matchOrder driver license is match : {}, {}", dWaybill.getId(), driver.getPhone());
                            licenseIsMatch = true;
                            waybill = dWaybill;
                            break;
                        } else {
                            continue;
                        }
                    }
                }

            }

            // 司机意向线路不匹配
            if( !lineIsMatch ){
                LOGGER.error("TmsQueueDimensionServiceImpl.matchOrder driver lines not match");
                throw new BusinessException(TmsDispatchOptionCodeEnum.DRIVER_LINE_NOT_MATCH.getValue()+"", TmsDispatchOptionCodeEnum.DRIVER_LINE_NOT_MATCH.getText());
            }

            // 司机驾照不匹配
            if( !licenseIsMatch ){
                LOGGER.error("TmsQueueDimensionServiceImpl.matchOrder driver lines not match");
                throw new BusinessException(TmsDispatchOptionCodeEnum.DRIVER_LICENSE_NOT_MATCH.getValue()+"", TmsDispatchOptionCodeEnum.DRIVER_LICENSE_NOT_MATCH.getText());
            }

            String userPhone = driver.getPhone();

            // 派单
            this.dWaybillService.dispatchDWaybill(waybill, userPhone, false);

            /**
             * 派单成功时移除司机和运单
             */
            TmsQueueApi.removeOrder(waybill.getId().toString(), waybill.getOrderLineId().toString());
            TmsQueueApi.removeDriver(driver);

            // push消息给司机 TODO司机发短信注释
            sendMessageService.sendDispatchMessage(waybill.getOrderCode(), driver.getPhone());
            // push价格给tms
            dWaybillService.pushPrice2tms(waybill.getOrderCode());
        } catch (Exception e) {

            LOGGER.error("TmsQueueDimensionServiceImpl.matchOrder error : {}, {} ,{}", redisWaybill, driver, e);

            if (e instanceof BusinessException) {
                String messageCode = ((BusinessException) e).getMessageCode();

                this.handleError(redisWaybill, driver, messageCode, e);
            }

        } finally {
            // 继续派单
            this.dispatch();
        }
    }

    private void handleErrorForDWaybill(TmsQueueOrderVo redisWaybill, TmsQueueDriverVo driver, Exception e) {
        LOGGER.info("TmsQueueDimensionServiceImpl.handleErrorForDWaybill params : {}, {}, {}", redisWaybill, driver, e);

        /**
         * FIXME
         * 逻辑错误，应该区分错误是由tms返回，还是由系统内部判断返回
         */
        if (null != redisWaybill) {
            dWaybillService.updateIsError(NumberUtils.toLong(redisWaybill.getWaybillId()));
        }

        /**
         * 保存派单错误信息
         */
        DWaybillErrorMsg errorMsg = new DWaybillErrorMsg();
        if (null != redisWaybill) {
            errorMsg.setWaybillId(NumberUtils.toLong(redisWaybill.getWaybillId()));
            errorMsg.setWaybillLineId(NumberUtils.toInt(redisWaybill.getTmsSerialNo()));
        }
        if (null != driver) {
            /**
             *  qichao
             *  FIXME 整个账号体系需要重构
             *  校验当前司机是否存在，若不存在，则移除司机（当前是从redis取司机信息，根据司机的手机号，去mysql取意向路线，若后台变更了司机的手机号，则会NPE）
             */
            if(Objects.equals(userService.getUserByPhone(driver.getPhone()),null)){
                LOGGER.info("============司机手机号已在后台变更，日志表中不记录ID==============");
                errorMsg.setUserId(null);
            }else{
                errorMsg.setUserId(userService.getUserByPhone(driver.getPhone()).getId());
            }
            errorMsg.setUserPhone(driver.getPhone());
        }
        errorMsg.setIsHandle(false);
        if (e instanceof BusinessException) {
            errorMsg.setErrCode(((BusinessException) e).getMessageCode());
        }
        errorMsg.setErrMsg(e.getMessage());
        dWaybillErrorMsgService.add(errorMsg);
    }

    private void handleError(TmsQueueOrderVo redisWaybill, TmsQueueDriverVo driver, String messageCode, Exception e) throws Exception  {
        LOGGER.info("TmsQueueDimensionServiceImpl.handleError param : {}, {}, {}", redisWaybill, driver, messageCode);

        /**
         * 错误时运单的处理
         */
        this.handleErrorForDWaybill(redisWaybill, driver, e);

        if (messageCode.startsWith("1")) {

            String userPhone = driver.getPhone();

            boolean isRemoveDriver = true;

            /**
             * DRIVER_INFO_ERROR(0, "获取司机关联信息失败"),
             * DRIVER_HAS_NO_IDCARD(101, "需要提供身份证号"),
             * DRIVER_HAS_NO_PHONE_NO(102, "需要提供手机号"),
             * DRIVER_UPDATE_INFO_ERROR(103, "读取/更新司机信息错误"),
             * DRIVER_IS_NOT_TMS_DRIVER(104, "非知车司机，不可以安排"),
             * DRIVER_HAS_NO_LICENSE(106, "司机缺少驾照类型"),
             * DRIVER_LICENSE_NOT_MATCH(107, "司机驾照不匹配"),
             * DRIVER_LICENSE_NOT_MATCH(107, "司机线路不匹配"),
             * DRIVER_HAS_NO_INTENTIONA_LINE(108, "司机缺少意向线路"),
             * DRIVER_IS_DISABLE(109, "司机不可用"),
             * DRIVER_ALREADY_HAVE_WAYVILL(110, "司机已经有未完成的运单"),
             * DRIVER_INFO_SYSTEM_ERROR(111, "系统司机信息错误"),
             */

            if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_INFO_ERROR.getValue() + "")) {
                this.sendMessageService.sendByTplId(JavaSmsApi.DRIVER_INFO_ERROR, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_IDCARD.getValue() + "")) {
                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_HAS_NO_IDCARD, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_PHONE_NO.getValue() + "")) {
                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_HAS_NO_PHONE_NO, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_UPDATE_INFO_ERROR.getValue() + "")) {
                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_UPDATE_INFO_ERROR, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_IS_NOT_TMS_DRIVER.getValue() + "")) {
                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_IS_NOT_TMS_DRIVER, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_LICENSE.getValue() + "")) {
                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_HAS_NO_LICENSE, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_LICENSE_NOT_MATCH.getValue() + "") || messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_LINE_NOT_MATCH.getValue() + "")) {

                isRemoveDriver = false;

                /**
                 * 保持司机位置，抓取司机是index+1
                 */
                this.driverIndex += 1;

//                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_LICENSE_NOT_MATCH, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_INTENTIONA_LINE.getValue() + "")) {
                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_HAS_NO_INTENTIONA_LINE, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_IS_DISABLE.getValue() + "")) {
                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_IS_DISABLE, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_ALREADY_HAVE_WAYBILL.getValue() + "")) {
                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_ALREADY_HAVE_WAYVILL, userPhone);
            } else if (messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_INFO_SYSTEM_ERROR.getValue() + "")) {
//                sendMessageService.sendByTplId(JavaSmsApi.DRIVER_INFO_SYSTEM_ERROR, userPhone);
            }else if(messageCode.equals(TmsDispatchOptionCodeEnum.DRIVER_WRONG_PHONE_NO.getValue()+"")){
                //do nth
            }

            if (isRemoveDriver) {
                /**
                 * 异常时移除司机
                 */
                TmsQueueApi.removeDriver(driver);
            }

        } else if (messageCode.startsWith("3")) {

            /**
             * 废弃运单
             *
             * NO_TMS_ORDER(302, "该订单非人送订单，请确定数据"),//TMS
             * NO_TMS_ORDER_TEAM(303, "该订单对应的指令不属于人送提车队，不可以安排"),//TMS
             * IS_SEND_ORDER(304, "该订单已发车，不可以安排"),//TMS
             * ADD_DRIVER_ERROR(305, "新增司机更换表 错误"),//TMS
             * WAYBILL_IS_NULL(309, "运单为空"),
             * WAYBILL_HAS_BEEN_SENT(310, "运单已经安排给其他司机"),
             */
            if ( messageCode.equals(TmsDispatchOptionCodeEnum.NO_TMS_ORDER.getValue() + "")
                    || messageCode.equals(TmsDispatchOptionCodeEnum.NO_TMS_ORDER_TEAM.getValue() + "")
                    || messageCode.equals(TmsDispatchOptionCodeEnum.IS_SEND_ORDER.getValue() + "")
                    || messageCode.equals(TmsDispatchOptionCodeEnum.ADD_DRIVER_ERROR.getValue() + "")
                    || messageCode.equals(TmsDispatchOptionCodeEnum.WAYBILL_IS_NULL.getValue() + "")
                    || messageCode.equals(TmsDispatchOptionCodeEnum.WAYBILL_HAS_BEEN_SENT.getValue() + "") ) {

                dWaybillService.updateAbandoned(Long.parseLong(redisWaybill.getWaybillId()), Integer.parseInt(messageCode),
                        TmsDispatchOptionCodeEnum.getByValue(Integer.parseInt(messageCode)).getText());
            }

            /**
             *  异常时移除队列订单
             */
            TmsQueueApi.removeOrder(redisWaybill);
        }
    }

    /**
	 * 判断司机准驾车型
	 * @param tqov 订单对象
	 * @param tqdv 司机对象
	 * @return 是否匹配
	 */
	private boolean filterAvailableDriver(TmsQueueOrderVo tqov, TmsQueueDriverVo tqdv) {
		// 获取车型编号
		DWaybill wd = this.dWaybillMapper.selectByPrimaryKey(NumberUtils.toLong(tqov.getWaybillId()));
		if (null != wd) {
			TmsOrder to = this.tmsOrderMapper.selectByPrimaryKey(wd.getTmsOrderId());
			if (null != to) {
				// 获取车型准驾信息
				DVcstyleLicenseExample dve = new DVcstyleLicenseExample();
				dve.createCriteria().andVcstylecodeEqualTo(to.getVcstyleno());
				List<DVcstyleLicense> list = this.dVcstyleLicenseMapper.selectByExample(dve);
				DVcstyleLicense dvl = list.size() > 0 ? list.get(0) : null;
				if (null != dvl) {
					// 订单准驾车型
					String vcLicense = dvl.getLicense();
					// 获取用户驾照信息
					String driverLicense = tqdv.getLicense();
					LOGGER.info("================filterAvailableDriver====获取准驾信息=========订单准驾{}, 司机驾照{}, 司机手机号{}", vcLicense, driverLicense, tqdv.getPhone());
					return this.matchLicense(vcLicense, driverLicense);
				}
			}
		}
		// 校验驾照信息
		return false;
	}
	
	/**
	 * 匹配驾照类型
	 * @param vcLicense  准驾车型
	 * @param driverLicense 司机驾照
	 * @return 是否匹配
	 */
	private boolean matchLicense(String vcLicense, String driverLicense) {
		// 判空
		if (StringUtils.isNotBlank(vcLicense) && StringUtils.isNotBlank(driverLicense)) {
			// 司机驾照
			String[] vcLicenseLicenseArray = vcLicense.replaceAll("，", ",").toUpperCase().split(",");
			String[] driverLicenseArray = driverLicense.replaceAll("，", ",").toUpperCase().split(",");
			for (String o : vcLicenseLicenseArray) {
				String oString = o.trim();
				for (String d : driverLicenseArray) {
					if (StringUtils.isNotBlank(d) && oString.equals(d.trim())) {
						return true;
					}
				}
			}
			// return this.matchLicense4down(vcLicense, driverLicenseArray);
		}
		return false;
	}
	
	/**
	 * 获取驾照向下兼容
	 * @param vcLicense
	 * @param driverLicense
	 * @return 是否匹配
	 */
	private boolean matchLicense4down(String vcLicense, String[] driverLicense) {
		int maxOrderLicense = this.getFirst4Sort(vcLicense.split(","), true);
		int minDriverLicense = this.getFirst4Sort(driverLicense, false);
		if (minDriverLicense <= maxOrderLicense) {
			return true;
		}
		return false;
	}
	
	/**
	 * 获取排序数组第一个值
	 * @param sortString 排序字符数组
	 * @param isDesc 是否降序排列，默认升序
	 * @return 第一个数组值
	 */
	private int getFirst4Sort(String[] sortString, boolean isDesc) {
		// 获取字符串数字类型数组，便于计算
		int lengthVal = sortString.length;
		if (lengthVal <= 0) {
			return 0;
		}
		int[] sortInt = new int[lengthVal];
		for (int i = 0; i < lengthVal; i++) {
			sortInt[i] = Integer.valueOf(sortString[i], 16);
		}
		Arrays.sort(sortInt);
		return isDesc ? sortInt[lengthVal - 1] : sortInt[0];
	}
	
	/**
	 * 过滤可用订单
	 * @param redisWaybill 订单对象
	 * @param list 司机意愿路线
	 * @return 是否可用
	 */
	private boolean filterAvailableOrder(TmsQueueOrderVo redisWaybill, List<TmsBareaVo> list) {
	    LOGGER.info("TmsQueueDimensionServiceImpl.filterAvailableOrder params : {}, {}", redisWaybill, list);

        String waybillId = redisWaybill.getWaybillId();
        DWaybill dw = this.dWaybillMapper.selectByPrimaryKey(NumberUtils.toLong(waybillId));
        if (null == dw) {
            LOGGER.info("TmsQueueDimensionServiceImpl.filterAvailableOrder must not be null");

            throw new BusinessException(TmsDispatchOptionCodeEnum.WAYBILL_IS_NULL.getValue() + "", TmsDispatchOptionCodeEnum.WAYBILL_IS_NULL.getText());
        }
        // 过滤意向路线
        boolean isHasIntentionalLines = false;
        for (TmsBareaVo bv : list) {
            if (bv.getIsCheck()) {
                isHasIntentionalLines = true;
                if (this.filterIntentionalLines(dw, bv)) {
                    return true;
                }
            }
        }
        if (!isHasIntentionalLines) {
            return true;
        }
        return false;
    }

    /**
     * 过滤意向路线
     *
     * @param dw 运单对象
     * @param bv 意向路线对象
     * @return 结果集
     */
    private boolean filterIntentionalLines(DWaybill dw, TmsBareaVo bv) {
        if (null != dw) {
            try {
                String destProvince = dw.getDestProvince().trim();
                String intentionalProvince = bv.getName().trim();
                if (destProvince.replaceAll(provinceSuffix, "").replaceAll(citySuffix, "").equals(intentionalProvince.replaceAll(provinceSuffix, "").replaceAll(citySuffix, ""))) {
//                    System.out.println("TmsQueueDimensionServiceImpl.filterIntentionalLines driver ");
                    LOGGER.info("================匹配成功，运单ID：{}, 订单目的地：{}, 意向路线：{}=========", dw.getId(), destProvince, intentionalProvince);
                    return true;
                }
            } catch (Exception e) {
                LOGGER.error("================匹配意向城市异常：{}=========", e);
            }
        }
        // LOGGER.info("================没有运单信息，运单ID：{}=========", dw.getId());
        return false;
    }

    /**
     * 校验准驾车型
     *
     * @param redisOrder  订单信息
     * @param redisDriver 司机信息
     * @return
     */
    private boolean validVcStyleLicense(TmsQueueOrderVo redisOrder, TmsQueueDriverVo redisDriver, DWaybill dWaybill) throws Exception {

        LOGGER.info("TmsQueueDimensionServiceImpl.validVcStyleLicense params : {}, {}", redisOrder, redisDriver);

        if (null == redisOrder) {
            LOGGER.error("TmsQueueDimensionServiceImpl.validVcStyleLicense params redisOrder must not null");
            throw new BusinessException("300", "运单信息为空");
        }
        if (null == redisDriver) {
            LOGGER.error("TmsQueueDimensionServiceImpl.validVcStyleLicense params redisDriver must not null");
            throw new BusinessException("300", "司机信息为空");
        }

        /**
         * 判断司机有没有驾照类型
         */
        String driverVoLicense = redisDriver.getLicense();

        if (StringUtils.isBlank(driverVoLicense) || !(driverVoLicense.split(",").length > 0)) {

            LOGGER.info("TmsQueueDimensionServiceImpl.validVcStyleLicense driver has no license type : {}", redisDriver.getPhone());
            throw new BusinessException(TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_LICENSE.getValue() + "", TmsDispatchOptionCodeEnum.DRIVER_HAS_NO_LICENSE.getText());
        }

        //获得准驾车型
        DWaybillVehicle waybillVehicle = dWaybillVehicleService.getByDWaybillId(dWaybill.getId());

        if (Objects.equals(waybillVehicle, null)) {
            LOGGER.info("TmsQueueDimensionServiceImpl.validVcStyleLicense waybillVehicle is null waybillId: {}", dWaybill.getId());
        }

        String vcstyleno = waybillVehicle.getVehicleTypeCode();

        DVcstyleLicense dVcstyleLicense = dVcstyleLicenseService.getVcStyleByStyleCode(vcstyleno);
        if (null == dVcstyleLicense || StringUtils.isBlank(dVcstyleLicense.getLicense())) {
            LOGGER.info("TmsQueueDimensionServiceImpl.validVcStyleLicense driver has no license base data : {}", redisDriver.getPhone());
            throw new BusinessException(TmsDispatchOptionCodeEnum.WAYBILL_VEHICLE_HAS_NO_LICENSE_BASE_DATA.getValue() + "", TmsDispatchOptionCodeEnum.WAYBILL_VEHICLE_HAS_NO_LICENSE_BASE_DATA.getText());
        }

        String license = dVcstyleLicense.getLicense().toUpperCase();
        driverVoLicense = driverVoLicense.toUpperCase();
        String[] driverVoLicenseArray = driverVoLicense.split(",");

        // 是否匹配
        for (int i = 0; i < driverVoLicenseArray.length; i++) {
            if (license.contains(driverVoLicenseArray[i])) {
                return true;
            }
        }

        return false;
    }

}
